<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // Promise的静态方法 => 构造函数Promise自己的方法
    // console.dir(Promise)

    // Promise.all()   Promise.all()方法用于将多个 Promise 实例，包装成一个新的 Promise 实例。
    // const p = Promise.all([p1, p2, p3]);
    // 上面代码中，Promise.all()方法接受一个数组作为参数，p1、p2、p3都是 Promise 实例，如果不是，就会先调用下面讲到的Promise.resolve方法，将参数转为 Promise 实例，
    // p的状态由p1、p2、p3决定，分成两种情况。
    // （1）只有p1、p2、p3的状态都变成fulfilled，p的状态才会变成fulfilled，此时p1、p2、p3的返回值组成一个数组，传递给p的回调函数。
    // （2）只要p1、p2、p3之中有一个被rejected，p的状态就变成rejected，此时第一个被reject的实例的返回值，会传递给p的回调函数。
    //  处理多请求同时发送  => 按顺序返回结果,结果放到数组中


    // Promise.race()   Promise.race()方法用于将多个 Promise 实例，包装成一个新的 Promise 实例。
    // const p = Promise.all([p1, p2, p3]);
    // 只要p1、p2、p3之中有一个实例率先改变状态(成功/失败都可以)，p的状态就跟着改变。那个率先改变的 Promise 实例的返回值，就传递给p的回调函数。


    // 模拟封装Promise.myRace();
    Promise.myRace = function (arr) { // 方法接收数组,数组中可以存放多个Promise实例  [p1,p2,p3]
        return new Promise(function (resolve, reject) {  // 返回新的Promise实例 => 等p1,p2,p3 全都成功就成功,有一个失败就失败 (异步)
          
            for (let i = 0; i < arr.length; i++) {
                let p = arr[i]; // 遍历得到数组中的每一个Promise实例  p1,p2,p3
                // 给每一个Promise实例绑定成功时执行的回调函数 => 先变状态的先执行 
                p.then(arg => {
                    resolve(arg);
                }).catch(err => {
                    reject(err);  // 有一个失败 => 立即改为已失败状态
                })

            }
        })
    }



    var p1 = getNumAsync(1, 2000);  // 2s => {<fulfilled>:1}
    var p2 = getNumAsync(2, 1000, false);  // 1s => {<fulfilled>:2}
    var p3 = getNumAsync(3, 3000);  // 3s => {<fulfilled>:3}

        
    // var p = Promise.myRace([p1, p2, p3]);
    var p = Promise.race([p1, p2, p3]);

    p.then(function(arg){
        console.log("fulfilled",arg);
    }).catch(function(err){
        console.log("rejected",err);
    })




    function getNumAsync(num, delay = 0, isFulfilled = true) {
        var p = new Promise(function (resolve, reject) {
            // 回调函数 -> 容器 -> 用来存放异步操作 (根据异步操作的结果改变状态)
            setTimeout(() => {
                isFulfilled ? resolve(num) : reject(num); // {<fulfilled>:1}
                // console.log(p);
            }, delay);
        })
        return p;  // {<pending>:undefined}
    }



</script>

</html>